package engine.logic.walk
{
	import engine.GameData;
	import engine.flag.GameDefine;
	import engine.flag.PlayerActionFlag;
	import engine.scene.SceneChangeManager;
	import engine.scene.player.BasePlayerModel;
	import engine.scene.player.IMove;
	import engine.scene.player.NpcModel;
	import engine.scene.player.PetModel;
	import engine.scene.player.PlayerModel;
	import engine.scene.player.RoleModel;
	
	import flash.geom.Point;
	

	/**
	 *	一般移动，（npc移动，普通玩家移动，地图不会滚轴） 
	 * @author lw
	 * 
	 */
	public class NormalMoveLogic implements IMoveLogic
	{
		protected var _speed			:	int		=	10;//25;
		
		/**
		 *	路径 (坐标点的集合)
		 */
		protected var _path			:	Array;
		
		/**
		 *	移动到第几步了 
		 */
		protected var _step			:	int;
		
		/**
		 *	当前坐标点 
		 */
		protected var _curePoint		:	Point;
		
		/**
		 *	移动到的下一步 
		 */
		protected var _nextPoint		:	Point;
		
		protected var _moveModel		:	IMove;
		
		protected var _moveing			:	Boolean;
		
		protected var _callBackFunc 	: 	Function;
		
		protected var _pList			: 	*; 
		
		/**界面超出比率*/		
		private var ratio:Number		=	0.75;
		
		/**
		 *	开始移动  
		 * @param curePoint	当前坐标
		 * @param path		路径
		 * @param es		移动结束时是否改变swf播放状态（0，待机；1,移动状态）
		 */
		public function startMove( moveModel : IMove, startPoint : Point, path : Array, callBackFunc : Function = null, pList : * = null ):void
		{
			_callBackFunc = callBackFunc;
			
			_pList		= pList;
			
			_moveing	= true;
			
			_moveModel	= moveModel;
			
			_curePoint 	= startPoint;
			
			_path 		= path;
			
//			
			
			//设置方向
			setPlayerDirection( _curePoint, _path[0] );
			
			//设置状态
			_moveModel.status = PlayerActionFlag.Run;
			var playmodel:PlayerModel = _moveModel as PlayerModel;
			
			if(GameData.SceneType == GameDefine.SceneType_CS ||
			    GameData.SceneType == GameDefine.SceneType_FamilyScene ||
				GameData.SceneType == GameDefine.SceneType_ForbiddenAreaScene)
			{
				WalkManager.getInstance().walkLogic.addWalkFunc(onMove);
			}
			else
			{
				if(playmodel is RoleModel)
				{
					WalkManager.getInstance().walkLogic.addWalkFunc(onMove);
				}
				else
				{
					WalkManager.getInstance().walkLogic.addOtherWalkFunc(onMove);
				}
			}
		}
		
		private function onMove():void
		{
			
			if( _curePoint == null || _path.length == 0  )
			{
				_path = [];
				return;
			}
			var playmodel:PlayerModel = _moveModel as PlayerModel;
			
			if(playmodel!=null)
			{
				if(!playmodel.visible)
				{
					return;
				}
				var oldPoint:Point = new Point(playmodel.x,playmodel.y);
				var newPoint:Point = new Point(_path[_step].x,_path[_step].y);
				if(playmodel.playerObj.Properties.Type == 1 && !(playmodel is RoleModel))
				{
					if(checkPosition(newPoint))
					{
						playmodel.x = newPoint.x;
						playmodel.y = newPoint.y;
						stopMove();
						return;
					}else
					{
						if(checkPosition(oldPoint))
						{
							playmodel.x = newPoint.x;
							playmodel.y = newPoint.y;
							stopMove();
							return;
						}
					}
				}
			}
			
		
			//向下一个坐标移动
			if ( swlk( _path[ _step ] ) )
			{//当与目标网格中心的距离小于速度，则移动到目标点
				
				//移动到节点
				correctionSwlk();
				if (_step >= _path.length)
				{//路径走完了
					stopMove();
				}else
				{//设置方向
					setPlayerDirection(_path[_step - 1], _path[_step]);
				}
			}
		}
		
		/**
		 * 走动(移动不精确)
		 * @param 	nextPonit 下一次坐标
		 * @return 是否需要校正(当速度大于距离，true)
		 */
		private function swlk(nextPonit : Point) : Boolean
		{
			//与下一个坐标还有多少距离
			var dx : Number = nextPonit.x - _curePoint.x;
			var dy : Number = nextPonit.y - _curePoint.y;
			
			//2点之间的直线距离
//			var distance : Number = Math.sqrt(dx * dx + dy * dy);
			var distance : Number = Point.distance(nextPonit, _curePoint);
			var radians : Number = Math.atan2(dy, dx);
			
			//一帧移动的速度：对应x，y坐标
			var xSpeed : Number = _speed * Math.cos(radians);
			var ySpeed : Number = _speed * Math.sin(radians);
			
			//这一次移动总共移动了多少距离
			move(xSpeed, ySpeed);
			
			return distance < _speed;
		}
		
		/**
		 * 走到节点(移动精确)
		 */
		private function correctionSwlk() : void 
		{
			move(_path[_step].x - _curePoint.x, _path[_step].y - _curePoint.y);
			
			_step ++;
		}
		
		/**
		 * 移动到的坐标
		 * @param x
		 * @param y
		 */
		protected function move(xDistance : int, yDistance : int):void
		{
			//保存当前坐标
			_curePoint = new Point(_curePoint.x + xDistance, _curePoint.y + yDistance);
			
			_moveModel.move(xDistance, yDistance);//人物移动
			var playermodel:BasePlayerModel = _moveModel as BasePlayerModel;
		}
		
		
		/**
		 * 界面超出处理
		 */		
		private function checkPosition(p:Point):Boolean
		{
			var playmodel:PlayerModel = _moveModel as PlayerModel;
//			if(playmodel)
//			{
			if(playmodel.parent == null) return false;
				var point:Point	=	playmodel.parent .localToGlobal(p);
				if( point.x  < 0     || point.x  > SceneChangeManager.getGameWidth() 
					|| point.y < 0 || point.y  > SceneChangeManager.getGameHeight() )
				{
//					trace("超出",p.x,p.y,playmodel.playerName);
					return true;
				}
//			}
//				trace("没有",p.x,p.y,playmodel.playerName);
			return false;
		}
		
		/**
		 * 设置玩家方向 2方向
		 * @param curePoint	当前所在坐标
		 * @param nextPoint	下一步移动到的坐标
		 *  
		 */
		private function setPlayerDirection(curePoint : Point, nextPoint : Point):void
		{
//			//计算人物所在的第几个方向	
			var direction : int = curePoint.x > nextPoint.x ? -1 : 1;
			_moveModel.direction = direction;
		}
		
		public function kiss():void
		{
			reset();
			
			if( null != _moveModel )
			{
				_moveModel.status = PlayerActionFlag.NormalWait;
			}
		}
		
		/**
		 *	停止移动 
		 */
		private function stopMove():void
		{
			reset();
			
			_moveModel.status = PlayerActionFlag.NormalWait;
			
			moveComplete();
		}
		
		public function reset():void
		{
			var playmodel:BasePlayerModel = _moveModel as BasePlayerModel;
			
			if(GameData.SceneType == GameDefine.SceneType_CS ||
				GameData.SceneType == GameDefine.SceneType_FamilyScene ||
				GameData.SceneType == GameDefine.SceneType_ForbiddenAreaScene)
			{
				WalkManager.getInstance().walkLogic.delWalkFunc(onMove);
			}
			else
			{
				if(playmodel is RoleModel)
				{
					WalkManager.getInstance().walkLogic.delWalkFunc(onMove);
				}
				else
				{
					WalkManager.getInstance().walkLogic.delOtherWalkFunc(onMove);
				}
			}
			
			_path 		= [];
			_step 		= 0;
		}
		
		protected function moveComplete():void
		{
			if(null != _callBackFunc)
			{
				if(null != _pList)
				{			
					_callBackFunc.call(null, _pList);
				}
				else
				{
					_callBackFunc.call();
				}
			}
			
			_moveing 	=	false;
		}

		public function get moveing():Boolean
		{
			return _moveing;
		}

		/**
		 *	移动速度 
		 */
		public function set speed( value : int ):void
		{
			_speed = value;
		}
	}
}